home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / gfx / show / mpeg2decodeWOS.lha / mpeg2decode / src / subspic.c < prev    next >
C/C++ Source or Header  |  1999-02-23  |  11KB  |  417 lines

  1. /* #define DEBUG */
  2. /* subspic.c, Frame buffer substitution routines */
  3.  
  4. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  5.  
  6. /*
  7.  * Disclaimer of Warranty
  8.  *
  9.  * These software programs are available to the user without any license fee or
  10.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  11.  * any and all warranties, whether express, implied, or statuary, including any
  12.  * implied warranties or merchantability or of fitness for a particular
  13.  * purpose.  In no event shall the copyright-holder be liable for any
  14.  * incidental, punitive, or consequential damages of any kind whatsoever
  15.  * arising from the use of these programs.
  16.  *
  17.  * This disclaimer of warranty extends to the user of these programs and user's
  18.  * customers, employees, agents, transferees, successors, and assigns.
  19.  *
  20.  * The MPEG Software Simulation Group does not represent or warrant that the
  21.  * programs furnished hereunder are free of infringement of any third-party
  22.  * patents.
  23.  *
  24.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  25.  * are subject to royalty fees to patent holders.  Many of these patents are
  26.  * general enough such that they are unavoidable regardless of implementation
  27.  * design.
  28.  *
  29.  */
  30.  
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <fcntl.h>
  34.  
  35. #include "config.h"
  36. #include "global.h"
  37.  
  38. /* private prototypes*/
  39. static void Read_Frame _ANSI_ARGS_((char *filename, 
  40.   unsigned char *frame_buffer[], int framenum));
  41. static void Copy_Frame _ANSI_ARGS_((unsigned char *src, unsigned char *dst, 
  42.   int width, int height, int parity, int incr));
  43. static int Read_Components _ANSI_ARGS_ ((char *filename, 
  44.   unsigned char *frame[3], int framenum));
  45. static int Read_Component _ANSI_ARGS_ ((char *fname, unsigned char *frame, 
  46.   int width, int height));
  47. static int Extract_Components _ANSI_ARGS_ ((char *filename,
  48.   unsigned char *frame[3], int framenum));
  49.  
  50.  
  51. /* substitute frame buffer routine */
  52. #ifdef STORM
  53. void Substitute_Frame_Buffer (int bitstream_framenum, int sequence_framenum)
  54. #else
  55. void Substitute_Frame_Buffer (bitstream_framenum, sequence_framenum)
  56. int bitstream_framenum;
  57. int sequence_framenum;
  58. #endif
  59. {
  60.   /* static tracking variables */
  61.   static int previous_temporal_reference;
  62.   static int previous_bitstream_framenum;
  63.   static int previous_anchor_temporal_reference;
  64.   static int previous_anchor_bitstream_framenum;
  65.   static int previous_picture_coding_type;
  66.   static int bgate;
  67.   
  68.   /* local temporary variables */
  69.   int substitute_display_framenum;
  70.  
  71.  
  72. #ifdef DEBUG
  73.   printf("SUB: seq fn(%d) bitfn(%d) tempref(%d) picstr(%d) type(%d)\n", 
  74.     sequence_framenum, bitstream_framenum, temporal_reference, 
  75.     picture_structure, picture_coding_type);
  76. #endif
  77.  
  78.   /* we don't substitute at the first picture of a sequence */
  79.   if((sequence_framenum!=0)||(Second_Field))
  80.   {
  81.     /* only at the start of the frame */
  82.     if ((picture_structure==FRAME_PICTURE)||(!Second_Field))
  83.     {
  84.       if(picture_coding_type==P_TYPE)
  85.       {
  86.         /* the most recently decoded reference frame needs substituting */
  87.         substitute_display_framenum = bitstream_framenum - 1;
  88.         
  89.         Read_Frame(Substitute_Picture_Filename, forward_reference_frame, 
  90.           substitute_display_framenum);
  91.       }
  92.       /* only the first B frame in a consequitve set of B pictures
  93.          loads a substitute backward_reference_frame since all subsequent
  94.          B frames predict from the same reference pictures */
  95.       else if((picture_coding_type==B_TYPE)&&(bgate!=1))
  96.       {
  97.         substitute_display_framenum = 
  98.           (previous_temporal_reference - temporal_reference) 
  99.             + bitstream_framenum - 1;
  100.  
  101.         Read_Frame(Substitute_Picture_Filename, backward_reference_frame, 
  102.           substitute_display_framenum);
  103.       }
  104.     } /* P fields can predict from the two most recently decoded fields, even
  105.          from the first field of the same frame being decoded */
  106.     else if(Second_Field && (picture_coding_type==P_TYPE))
  107.     {
  108.       /* our favourite case: the IP field picture pair */
  109.       if((previous_picture_coding_type==I_TYPE)&&(picture_coding_type==P_TYPE))
  110.       {
  111.         substitute_display_framenum = bitstream_framenum;
  112.       }
  113.       else /* our more generic P field picture pair */
  114.       {
  115.         substitute_display_framenum = 
  116.           (temporal_reference - previous_anchor_temporal_reference) 
  117.             + bitstream_framenum - 1;
  118.       }
  119.  
  120.       Read_Frame(Substitute_Picture_Filename, current_frame, substitute_display_framenum);
  121.     }
  122. #ifdef DEBUG
  123.     else if((picture_coding_type!=B_TYPE)||(picture_coding_type!=D_TYPE))
  124.     {
  125.       printf("NO SUBS FOR THIS PICTURE\n");
  126.     }
  127. #endif
  128.   }
  129.  
  130.  
  131.   /* set b gate so we don't redundantly load next time around */
  132.   if(picture_coding_type==B_TYPE)
  133.     bgate = 1;
  134.   else
  135.     bgate = 0;
  136.  
  137.   /* update general tracking variables */
  138.   if((picture_structure==FRAME_PICTURE)||(!Second_Field))
  139.   {
  140.     previous_temporal_reference  = temporal_reference;
  141.     previous_bitstream_framenum  = bitstream_framenum;
  142.   }
  143.   
  144.   /* update reference frame tracking variables */
  145.   if((picture_coding_type!=B_TYPE) && 
  146.     ((picture_structure==FRAME_PICTURE)||Second_Field))
  147.   {
  148.     previous_anchor_temporal_reference  = temporal_reference;
  149.     previous_anchor_bitstream_framenum  = bitstream_framenum;
  150.   }
  151.  
  152.   previous_picture_coding_type = picture_coding_type;
  153.  
  154. }
  155.  
  156.  
  157. /* Note: fields are only read to serve as the same-frame reference for 
  158.    a second field */
  159. #ifdef STORM
  160. static void Read_Frame(char *fname,unsigned char *frame[],int framenum)
  161. #else
  162. static void Read_Frame(fname,frame,framenum)
  163. char *fname;
  164. unsigned char *frame[];
  165. int framenum;
  166. #endif
  167. {
  168.   int parity;
  169.   int rerr = 0;
  170.   int field_mode;
  171.  
  172.   if(framenum<0)
  173.     printf("ERROR: framenum (%d) is less than zero\n", framenum);
  174.  
  175.  
  176.   if(Big_Picture_Flag)
  177.     rerr = Extract_Components(fname, substitute_frame, framenum);
  178.   else
  179.     rerr = Read_Components(fname, substitute_frame, framenum);
  180.  
  181.   if(rerr!=0)
  182.   {
  183.     printf("was unable to substitute frame\n");
  184.   }
  185.  
  186.   /* now copy to the appropriate buffer */
  187.   /* first field (which we are attempting to substitute) must be
  188.      of opposite field parity to the current one */
  189.   if((Second_Field)&&(picture_coding_type==P_TYPE))
  190.   {
  191.     parity      = (picture_structure==TOP_FIELD ? 1:0);      
  192.     field_mode  = (picture_structure==FRAME_PICTURE ? 0:1);
  193.   }
  194.   else
  195.   {
  196.     /* Like frame structued pictures, B pictures only substitute an entire frame 
  197.        since both fields always predict from the same frame (with respect 
  198.        to forward/backwards directions) */
  199.     parity = 0;
  200.     field_mode = 0;
  201.   }
  202.  
  203.  
  204.   Copy_Frame(substitute_frame[0], frame[0], Coded_Picture_Width, 
  205.     Coded_Picture_Height, parity, field_mode);
  206.   
  207.   Copy_Frame(substitute_frame[1], frame[1], Chroma_Width, Chroma_Height, 
  208.     parity, field_mode);
  209.   
  210.   Copy_Frame(substitute_frame[2], frame[2], Chroma_Width, Chroma_Height,
  211.     parity, field_mode);
  212.  
  213. #ifdef VERBOSE
  214.   if(Verbose_Flag > NO_LAYER)
  215.     printf("substituted %s %d\n",
  216.       (field_mode ? (parity?"bottom field":"bottom field"):"frame"), framenum);
  217. #endif
  218. }
  219.  
  220.  
  221.  
  222.  
  223. #ifdef STORM
  224. static int Read_Components(char *filename, unsigned char *frame[3], int framenum)
  225. #else
  226. static int Read_Components(filename, frame, framenum)
  227. char *filename;
  228. unsigned char *frame[3];
  229. int framenum;
  230. #endif
  231. {
  232.   int err = 0;
  233.   char outname[FILENAME_LENGTH];
  234.   char name[FILENAME_LENGTH];
  235.  
  236.   sprintf(outname,filename,framenum);
  237.  
  238.  
  239.   sprintf(name,"%s.Y",outname);
  240.   err += Read_Component(name, frame[0], Coded_Picture_Width, 
  241.     Coded_Picture_Height);
  242.  
  243.   sprintf(name,"%s.U",outname);
  244.   err += Read_Component(name, frame[1], Chroma_Width, Chroma_Height);
  245.  
  246.   sprintf(name,"%s.V",outname);
  247.   err += Read_Component(name, frame[2], Chroma_Width, Chroma_Height);
  248.  
  249.   return(err);
  250. }
  251.  
  252.  
  253. #ifdef STORM
  254. static int Read_Component(char *Filename, unsigned char *Frame, int Width, int Height)
  255. #else
  256. static int Read_Component(Filename, Frame, Width, Height)
  257. char *Filename;
  258. unsigned char *Frame;
  259. int Width;
  260. int Height;
  261. #endif
  262. {
  263.   int Size;
  264.   int Bytes_Read;
  265.   int Infile;
  266.  
  267.   Size = Width*Height;
  268.  
  269. #ifdef DEBUG
  270.   printf("SUBS: reading %s\n", filename);
  271. #endif
  272.  
  273.   if(!(Infile=open(Filename,O_RDONLY|O_BINARY))<0)
  274.   {
  275.     printf("ERROR: unable to open reference filename (%s)\n", Filename);
  276.     return(-1);
  277.   }
  278.  
  279.   Bytes_Read = read(Infile, Frame, Size);
  280.   
  281.   if(Bytes_Read!=Size)
  282.   {
  283.     printf("was able to read only %d bytes of %d of file %s\n",
  284.       Bytes_Read, Size, Filename);
  285.   }
  286.  
  287.   close(Infile); 
  288.   return(0);
  289. }
  290.  
  291.  
  292. /* optimization: do not open the big file each time. Open once at start
  293.    of decoder, and close at the very last frame */
  294.  
  295. /* Note: "big" files were used in E-mail exchanges almost exclusively by the 
  296.    MPEG Committee's syntax validation and conformance ad-hoc groups from 
  297.    the year 1993 until 1995 */
  298. #ifdef STORM
  299. static int Extract_Components(char *filename, unsigned char *frame[3], int framenum)
  300. #else
  301. static int Extract_Components(filename, frame, framenum) 
  302. char *filename;
  303. unsigned char *frame[3];
  304. int framenum;
  305. #endif
  306. {
  307. /*  int err = 0; */
  308.   FILE *fd;
  309.   int line;
  310.   int size, offset;
  311.  
  312.  
  313.   if (!(fd = fopen(filename,"rb")))
  314.   {
  315.     sprintf(Error_Text,"Couldn't open %s\n",filename);
  316.     return(-1);
  317.   }
  318.  
  319.   /* compute size of each frame (in bytes) */
  320.   size = (Coded_Picture_Width*Coded_Picture_Height);
  321.  
  322.   if(chroma_format==CHROMA444)
  323.     size = (size * 3);
  324.   else if(chroma_format==CHROMA422)
  325.     size = (size * 2);
  326.   else if(chroma_format==CHROMA420)
  327.     size = ((size*3)>>1);
  328.   else
  329.     printf("ERROR: chroma_format (%d) not recognized\n", chroma_format);
  330.  
  331.  
  332.   /* compute distance into "big" file */
  333.   offset = size*framenum;
  334.  
  335. #ifdef DEBUG
  336.   printf("EXTRACTING: frame(%d) offset(%d), size (%d) from %s\n", 
  337.     framenum, offset, size, filename);
  338. #endif
  339.  
  340.   /* seek to location in big file where desired frame begins */
  341.   /* note: this offset cannot exceed a few billion bytes due to the */
  342.   /*       obvious limitations of 32-bit integers */
  343.   fseek(fd, offset, 0);
  344.  
  345.   /* Y  */
  346.   for (line=0; line<Coded_Picture_Height; line++)
  347.   {
  348.     fread(frame[0]+(line*Coded_Picture_Width),1,Coded_Picture_Width,fd);
  349.   }
  350.  
  351.   /* Cb */
  352.   for (line=0; line<Chroma_Height; line++)
  353.   {
  354.     fread(frame[1]+(line*Chroma_Width),1,Chroma_Width,fd);
  355.   }
  356.  
  357.   /* Cr */
  358.   for (line=0; line<Chroma_Height; line++)
  359.   {
  360.     fread(frame[2]+(line*Chroma_Width),1,Chroma_Width,fd);
  361.   }
  362.  
  363.  
  364.   fclose(fd);
  365.   return(0);
  366. }
  367.  
  368.  
  369. #ifdef STORM
  370. static void Copy_Frame(unsigned char *src, unsigned char *dst, int width, int height, int parity, int field_mode)
  371. #else
  372. static void Copy_Frame(src, dst, width, height, parity, field_mode)
  373. unsigned char *src;
  374. unsigned char *dst;
  375. int width;
  376. int height;
  377. int parity;        /* field parity (top or bottom) to overwrite */
  378. int field_mode;    /* 0 = frame, 1 = field                      */
  379. #endif
  380. {
  381.   int row, col;
  382.   int s, d;
  383.   int incr;
  384.  
  385.   s = d = 0;
  386.  
  387. #ifdef DEBUG
  388.   printf("COPYING (w=%d, h=%d, parity=%d, field_mode=%d)\n",
  389.     width,height,parity,field_mode);
  390. #endif /* DEBUG */
  391.  
  392.   if(field_mode)
  393.   {
  394.     incr = 2;
  395.  
  396.     if(parity==0)
  397.       s += width;
  398.   }
  399.   else
  400.   {
  401.     incr = 1;
  402.   }
  403.  
  404.   for(row=0; row<height; row+=incr) 
  405.   {
  406.     for(col=0; col<width; col++)
  407.     {
  408.       dst[d+col] = src[s+col];
  409.     }
  410.     
  411.     d += (width*incr);
  412.     s += (width*incr);
  413.   }
  414.  
  415. }
  416.  
  417.